/*
 * Copyright (c) 2010-2013 Ruben Chakhmakhchyan. All rights reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Eclipse Public License
 * Version 1.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/EPL-1.0 and read it before using this file.
 */

#pragma once


#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // exclude rarely-used stuff from Windows headers
#endif
#include <windows.h>
#else
#error system not recognized...
#endif

#define TWH_CMP_MSC

#include "twain.h"

//#ifdef TWH_CMP_MSC
//#define MSG_STOPFEEDER   0x0702
//#endif


#ifdef TWH_CMP_MSC
#pragma pack (push, before_twain)
#pragma pack (2)
#else
#pragma pack(2)
#endif // TWH_CMP_MSC

// The following structures combinations are implimented and found in the TWAIN specifications
//              BOOL  INT8  INT16  INT32  UINT8  UINT16  UINT32  STR32  STR64  STR128  STR255  STR1024  UNI512  FIX32  FRAME
// OneValue      x           x      x             x       x       x             x       x                        x      x
// Array                                   x      x       x       x                                              x      x
// Enumeration   x           x                    x       x       x                     x                        x      x
// Range                     x      x             x       x                                                      x      


#define TWT( cat, type ) typedef TW_##cat##_T< TW_##type > TW_##cat##_##type, FAR *pTW_##cat##_##type;


template< typename T >
struct TW_ONEVALUE_T
{
	TW_UINT16 ItemType;
	T Item;
};

TWT( ONEVALUE, BOOL )
TWT( ONEVALUE, STR32 )
TWT( ONEVALUE, STR64 )
TWT( ONEVALUE, STR128 )
TWT( ONEVALUE, STR255 )
TWT( ONEVALUE, FIX32 )
TWT( ONEVALUE, FRAME )



template< typename T >
struct TW_ARRAY_T
{
	TW_UINT16 ItemType;
	TW_UINT32 NumItems;
	T ItemList[1];
};

TWT( ARRAY, UINT8 )
TWT( ARRAY, UINT16 )
TWT( ARRAY, UINT32 )
TWT( ARRAY, STR32 )
TWT( ARRAY, FIX32 )
TWT( ARRAY, FRAME )


template< typename T >
struct TW_ENUMERATION_T
{
	TW_UINT16 ItemType;
	TW_UINT32 NumItems;
	TW_UINT32 CurrentIndex;
	TW_UINT32 DefaultIndex;
	T ItemList[1];
};


TWT( ENUMERATION, BOOL )
TWT( ENUMERATION, INT16 )
TWT( ENUMERATION, INT32 )
TWT( ENUMERATION, UINT16 )
TWT( ENUMERATION, UINT32 )
TWT( ENUMERATION, STR32 )
TWT( ENUMERATION, STR64 )
TWT( ENUMERATION, STR128 )
TWT( ENUMERATION, STR255 )
TWT( ENUMERATION, FIX32 )
TWT( ENUMERATION, FRAME )


template< typename T >
struct TW_RANGE_T
{
	TW_UINT16 ItemType;
	T MinValue;
	T MaxValue;
	T StepSize;
	T DefaultValue;
	T CurrentValue;
};

TWT( RANGE, FIX32 )
TWT( RANGE, INT16 )
TWT( RANGE, UINT16 )
TWT( RANGE, INT32 )
TWT( RANGE, UINT32 )


#ifdef TWH_CMP_MSC
#pragma pack (pop, before_twain)
#else
#pragma pack() // reset
#endif // TWH_CMP_MSC


bool operator== ( const TW_FIX32& value1, const TW_FIX32& value2 );
float fix32ToFloat( const TW_FIX32& value );
TW_FIX32 floatToFIX32( float value );
TW_FIX32 floatToFIX32( double value );

int getTWTYsize( TW_UINT16  ItemType );
